\chapter{课程设计思路及完成任务} 
% \pagenumbering{arabic} % 阿拉伯数字页码
操作系统管理各种计算机硬件，为应用程序提供给基础，并充当计算机硬件与用户直接的中介，
它是硬件的第一层封装和抽象，在计算机系统中处于重要地位．
但是在实验中，大多会出现停留在应用层、不能深入到底层的情况．我认为，只有通过阅读研究
真实的操作系统源码并自己动手实践，才能较为深刻地理解原理．

\section{思路}
首先，目的明确：要造一个能够在计算机上直接运行的简易操作系统内核(不依赖于windows或Linux).
由于水平和精力所限，此次课设重点放在它的文件系统的实现上．
\subsection{开发环境}
我们操作系统内核的开发当然还是要在操作系统内进行．Linux下的工具链比Windows要完善一些，因此
选用GNU/Linux作为开发平台，笔者开发时具体选用的是Ubuntu Bionic Beaver (development branch)18.04．
是X86\_64架构．在进行本实验之前请先确保交叉编译的环境已经被正确建立起来了．

实验涉及到的开发工具有用于编译内核的gcc、x86机器的硬件模拟软件qemu，内核面向的CPU架构为IA-32,
由于x86系列芯片的后向兼容性，编译好内核还是可以在我们真实的计算机上运行，这是可验证的．
\subsection{主要特点}
\begin{itemize}
\item 编程用C和Ｃ++及少部分汇编语言
\item 面向x86,32位架构
\item 用GRUB2引导内核
\item 类似UNIX的风格
\item 文件系统面向IDE(ATA)硬盘，可读写、多级索引
\item 有简单的shell解释命令并运行
\end{itemize}
\subsection{运行流程}
\subparagraph{启动}
首先，加载内核工作从符合GRUB2的Multiboot规范的multiboot.asm开始，BIOS会对它进行进行检查，在boot.asm中，关中断
，然后跳向C语言写成的kmain.cc中的RiOS\underline{ }main函数．本系统并不是一个普通的应用层软件，
我们还需要一个链接脚本(linker.ld)来定义编译后可执行内核的结构，它定义了内核加载到
内存的位置，由于内存中前1MB含VGA显存空间、16位设备扩展ROM等预留空间，这里内核从1M
空间开始，(GRUB2的引导工作在此对程序员透明).这里有个很重要的工作就是定义C语言的调用函数时的栈大小，
不能定得过小，否则以后有可能出现栈溢出的情况，而且如果事先不知道的话将很难定位内核崩溃的原因．

\section{完成任务} 
\subparagraph{运行}
跳转到C语言写成的RiOS\_main函数以后，(当然，函数用什么写成对于编译好的二进制内核来说已经没什么意义了)
首先通过写显存的方法在屏幕打印字符，然后依次进行以下工作:
\begin{enumerate}
\item 初始化全局描述符表(global descriptor table).
\item 初始化字符设备驱动.
\item 初始化中断描述符表(interrupt descriptor table),这里设置了各个中断门，将编写好的
中断处理程序与中断向量表对应好，这里包括了键盘中断服务程序，完成了键盘扫描码的处理就可以用键盘输入了．
\item 完成定时器(8253或其兼容芯片)的设置
\item 内存管理上，通过简单连续分配实现内存的分配与回收
\item 控制台终端简易shell的实现，解释执行键盘输入的命令
\item 用类似处理中断的方法处理系统异常
\item 检测PC有多少磁盘，它假设磁盘0是存在的，因为内核就是从磁盘0加载的，然后检查磁盘１是否存在，
若磁盘1存在，就会通过写I/O端口0x1f6来选择磁盘1,本系统为了实现得更加清晰，默认磁盘０只用来存放内核并
完成加载内核的工作，内核的文件系统将建立在磁盘1上，因此请确保磁盘1存在．
\item 完成系统调用的设置
\item 初始化硬盘分区表，其中一步是检查磁盘某特定位置有无文件系统特定的Magic number,若无，则认为
文件系统尚未建立，将会格式化全盘，然后建立起整个文件系统;若Magic number存在，则不格式化，直接从
硬盘加载上次开机已写入的文件内容．
\item 于IDE(ATA)硬盘上建立文件系统，完成超级块的初始化设置，设置内存专用块，为用于数据区分配回收的
成组链接法做好准备;inode的分配回收则用位示图法;对文件采用多级索引;支持多级目录.
\end{enumerate}


% % \clearpage
